
NAMESPACE_BEGIN(interp)

template <class EncodingT>
shared_ptr< Base<EncodingT> > IncludeInstruction<EncodingT>::interpret(Context<EncodingT> & c)
{
    typename EncodingT::string_t buf;
    shared_ptr< Bool<EncodingT> > res(new Bool<EncodingT>(false));
    shared_ptr< Base<EncodingT> > expr = m_instruction->interpret(c);

    Category * logger = &Category::getInstance(LOGNAME);
    if (!readFile(A(expr->toString()), buf))
    {
        logger->errorStream() << "Cannot open file '" << A(expr->toString()) << "'.";
    }
    else
    {
        shared_ptr< Term<ucs> > value;
        if (Block<ucs>::parse(buf, value))
        {
            value->interpret(c);
            res->setValue(true);
        }
        else
        {
            logger->errorStream() << "An error occurred during the file interpretation '" << A(expr->toString()) << "'.";
        }
    }
    return res;
}

template <class EncodingT>
bool IncludeInstruction<EncodingT>::parse(typename EncodingT::string_t const& buf, shared_ptr< Term<EncodingT> > & value)
{
    typename EncodingT::string_t expr;
    shared_ptr< Term<EncodingT> > expr_value;
    bool success = prefix<EncodingT>(buf, C("include"), expr) && 
                   Bracket<EncodingT>::parse(expr, expr_value);
    if (success)
    {
        value.reset(new IncludeInstruction<EncodingT>(expr_value));
    }
    return success;
}

template <class EncodingT>
shared_ptr< Base<EncodingT> > PrintInstruction<EncodingT>::interpret(Context<EncodingT> & c)
{
    shared_ptr< Base<EncodingT> > expr = m_instruction->interpret(c);
    shared_ptr< String<EncodingT> > res(new String<EncodingT>(expr->toString()));

    cout << A(res->getValue()) << endl;

    return res;
}

template <class EncodingT>
bool PrintInstruction<EncodingT>::parse(typename EncodingT::string_t const& buf, shared_ptr< Term<EncodingT> > & value)
{
    typename EncodingT::string_t expr;
    shared_ptr< Term<EncodingT> > expr_value;
    bool success = prefix<EncodingT>(buf, C("print"), expr) && 
                   Bracket<EncodingT>::parse(expr, expr_value);
    if (success)
    {
        value.reset(new PrintInstruction<EncodingT>(expr_value));
    }
    return success;
}

NAMESPACE_END

